import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.border.Border;


/**
 * Copyright (C) 2013  Arun Lee & Bryce Nagareda
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Creates equatorial sundial
 * @author Arun Lee
 */
public class ESundialMath {
	private int latitude;
	private String timezone;
	private double[] hourlines;
	private double Gnomonlength;
	private double radius = 162.4;
	private DrawEDialFace drawF;
	private DrawEGnomon drawG;
	
	/**
	 * Constructor to set all the information to build a equatorial sundial
	 * @param lat
	 * @param tz
	 * @param hrl
	 */
	public ESundialMath(int lat, String tz, double[] hrl){
		this.latitude = lat;
		this.timezone = tz;
		this.hourlines = hrl;
		this.Gnomonlength = CalculateEGnomon(Math.abs(this.latitude));
		ESundialComponent();
	}
	
	/**
	 * function use to find the length of gnomon using given latitude
	 * @param lat
	 * @return
	 */
	public double CalculateEGnomon(int lat){
		if(lat < 0){
			return 0;
		}
		double gnomonlength = 0;
		double Radian;
		double latRadian = lat * Math.PI/180;
		if(lat < 45){
			Radian = (2*lat) * Math.PI/180;
			gnomonlength = (this.radius*Math.sin(Radian)) / Math.sin(latRadian);
		}
		else if (lat == 45){
			gnomonlength = this.radius/Math.sin(latRadian);
		}
		else if (lat <= 90){
			Radian = (180-2*lat) * Math.PI/180;
			gnomonlength = (this.radius*Math.sin(Radian)) / Math.sin(latRadian);
		}
		return gnomonlength;
	}
	
	/**
	 * creates the interface for user
	 */
	public void ESundialComponent(){
		JFrame frame = new JFrame("Equatorial Sundial");
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frame.setBackground(Color.white);
		
		this.drawG = new DrawEGnomon(this.latitude, this.timezone, this.radius, this.Gnomonlength);
		this.drawF = new DrawEDialFace(this.radius, this.hourlines, this.timezone);
		
		JPanel p1 = new JPanel();
		p1.setPreferredSize(new Dimension(200,200));
		JTextArea text = new JTextArea();
		Border mb = BorderFactory.createMatteBorder(2, 2, 2, 2, Color.red.brighter());
		p1.setBorder(mb);
		text.setFont(new Font("Arial", Font.BOLD, 15));
		text.setText("Instruction to build the horizontal sundial:\n"
				+ "\n-  Cut out the gnomon (pencil looking thing)"
				+ "\n-  Cut the little yellow line on dial face"
				+ "\n-  Fold all the blue lines"
				+ "\n-  Place the gnomon on the dial face"
				+ "\n-  Line up the marking on gnomon to the slit"
				+ "\n-  Use tape to hold them together if necessary"
				+ "\n-  TADA! you just made a Equatorial sundial "
				+ "\n\n\n Now take it out and face direction indicated " 
				+  "\n and see what time is it!");
		text.setEditable(false);
		p1.add(text);
		p1.setBackground(Color.white);
		p1.setPreferredSize(new Dimension(400, 400));
		
		JTabbedPane tp1 = new JTabbedPane();
		tp1.setBackground(Color.white);
		tp1.addTab("Gnomon", this.drawG);
		tp1.addTab("Dial Face", this.drawF);
		
		JPanel p2 = new JPanel();
		p2.setBackground(Color.white);
		JButton b1 = new JButton("Print");
		b1.addActionListener(new PrintButtonListener());
		p2.add(b1);
		p2.setPreferredSize(new Dimension(400, 50));
		
		frame.add(p1,BorderLayout.WEST);
		frame.add(tp1,BorderLayout.CENTER);
		frame.add(p2, BorderLayout.SOUTH);
		frame.pack();
		frame.setVisible(true);
	}
	
	/**
	 * accessor method for testing
	 * @return
	 */
	public int getlatitude(){
		return this.latitude;
	}
	/**
	 * accessor method for testing
	 * @return
	 */
	public String getTimeZone(){
		return this.timezone;
	}
	/**
	 * accessor method for testing
	 * @return
	 */
	public double[] getHourLines(){
		return this.hourlines;
	}
	/**
	 * accessor method for testing
	 * @return
	 */
	public double getRadius(){
		return this.radius;
	}
	
	/**
	 * Action listener for print button
	 * @author Arun
	 *
	 */
	private class PrintButtonListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent arg0) {
			print();
		}
	}
	/**
	 * open print dialog and enable printing activity
	 */
	private void print(){
		PrinterJob job = PrinterJob.getPrinterJob();
        PageFormat pf = job.defaultPage();
        pf.setOrientation(PageFormat.LANDSCAPE);
        //send DrawDialFace to printing 
        job.setPrintable(this.drawF, pf);
        boolean ok = job.printDialog();
        if (ok) {
            try {
                job.print();
            } catch (PrinterException ex) {
                /* The job did not successfully complete */
            	JOptionPane.showMessageDialog(null, "There was a problem printing");
            }
        }
        //send DrawGnomon to printing
        job.setPrintable(this.drawG, pf);
        ok = job.printDialog();
        if (ok) {
            try {
                job.print();
            } catch (PrinterException ex) {
                /* The job did not successfully complete */
            	JOptionPane.showMessageDialog(null, "There was a problem printing");
            }
        }
	}
	
	/**
	 * simple test
	 * @param args
	 */
	public static void main(String[] args){
		SundialMath test = null;
		try {
			test = new SundialMath(30, 109.86, 15, "April");
		} catch (MonthDayException e) {
			e.printStackTrace();
		}
		if (test != null) {
			ESundialMath test1 = new ESundialMath((test.getLatitude()), test.getTimeZoneName(), test.getHourLines());
		}
	}
}
